home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 90 / CD Actual 90.iso / Software3D / K-3D / k3d-0.4.2.1 / shaders / k3d_noises.h < prev    next >
Encoding:
C/C++ Source or Header  |  2004-07-23  |  9.4 KB  |  324 lines

  1. /************************************************************************
  2.  * noises.h - various noise-based patterns
  3.  *
  4.  * Author: Larry Gritz (gritzl@acm.org), though they're obvious to any
  5.  *         experience shader writer.
  6.  *
  7.  * Reference:
  8.  *   _Advanced RenderMan: Creating CGI for Motion Picture_, 
  9.  *   by Anthony A. Apodaca and Larry Gritz, Morgan Kaufmann, 1999.
  10.  *
  11.  * $Revision: 1.1 $    $Date: 2002/11/25 20:37:34 $
  12.  *
  13.  ************************************************************************/
  14.  
  15.  
  16. #ifndef NOISES_H
  17. #define NOISES_H 1
  18.  
  19.  
  20. #ifndef FILTERWIDTH_H
  21. #include "k3d_filterwidth.h"    /* Needed for filterwidth and friends */
  22. #endif
  23.  
  24. #ifndef PATTERNS_H
  25. #include "k3d_patterns.h"    /* Needed for filteredabs */
  26. #endif
  27.  
  28.  
  29.  
  30.  
  31. #ifndef snoise
  32. /*
  33.  * Signed noise -- the original Perlin kind with range (-1,1) We prefer
  34.  * signed noise to regular noise mostly because its average is zero.
  35.  * We define three simple macros:
  36.  *   snoise(p) - Perlin noise on either a 1-D (float) or 3-D (point) domain.
  37.  *   snoisexy(x,y) - Perlin noise on a 2-D domain.
  38.  *   vsnoise(p) - vector-valued Perlin noise on either 1-D or 3-D domain.
  39.  */
  40. #define snoise(p) (2 * (float noise(p)) - 1)
  41. #define snoisexy(x,y) (2 * (float noise(x,y)) - 1)
  42. #define vsnoise(p) (2 * (vector noise(p)) - 1)
  43. #endif
  44.  
  45.  
  46. /* If we know the filter size, we can crudely antialias snoise by fading
  47.  * to its average value at approximately the Nyquist limit.
  48.  */
  49. #define filteredsnoise(p,width) (snoise(p) * (1-smoothstep (0.2,0.75,width)))
  50. #define filteredvsnoise(p,width) (vsnoise(p) * (1-smoothstep (0.2,0.75,width)))
  51.  
  52.  
  53.  
  54. /* fractional Brownian motion
  55.  * Inputs: 
  56.  *    p, filtwidth   position and approximate inter-pixel spacing
  57.  *    octaves        max # of octaves to calculate
  58.  *    lacunarity     frequency spacing between successive octaves
  59.  *    gain           scaling factor between successive octaves
  60.  */
  61. float fBm (point p; float filtwidth;
  62.            uniform float octaves, lacunarity, gain)
  63. {
  64.     uniform float amp = 1;
  65.     varying point pp = p;
  66.     varying float sum = 0, fw = filtwidth;
  67.     uniform float i;
  68.  
  69.     for (i = 0;  i < octaves;  i += 1) {
  70. #pragma nolint
  71.     sum += amp * filteredsnoise (pp, fw);
  72.     amp *= gain;  pp *= lacunarity;  fw *= lacunarity;
  73.     }
  74.     return sum;
  75. }
  76.  
  77.  
  78. /* Typical use of fBm: */
  79. #define fBm_default(p)  fBm (p, filterwidthp(p), 4, 2, 0.5)
  80.  
  81.  
  82.  
  83.  
  84.  
  85. /* A vector-valued antialiased fBm. */
  86. vector
  87. vfBm (point p; float filtwidth;
  88.       uniform float octaves, lacunarity, gain)
  89. {
  90.     uniform float amp = 1;
  91.     varying point pp = p;
  92.     varying vector sum = 0;
  93.     varying float fw = filtwidth;
  94.     uniform float i;
  95.  
  96.     for (i = 0;  i < octaves;  i += 1) {
  97. #pragma nolint
  98.     sum += amp * filteredvsnoise (pp, fw);
  99.     amp *= gain;  pp *= lacunarity;  fw *= lacunarity;
  100.     }
  101.     return sum;
  102. }
  103.  
  104.  
  105. /* Typical use of vfBm: */
  106. #define vfBm_default(p)  vfBm (p, filterwidthp(p), 4, 2, 0.5)
  107.  
  108.  
  109.  
  110. /* The stuff that Ken Musgrave calls "VLNoise" */
  111. #define VLNoise(Pt,scale) (snoise(vsnoise(Pt)*scale+Pt))
  112. #define filteredVLNoise(Pt,fwidth,scale) \
  113.             (filteredsnoise(filteredvsnoise(Pt,fwidth)*scale+Pt,fwidth))
  114.  
  115.  
  116. float
  117. VLfBm (point p; float filtwidth;
  118.        uniform float octaves, lacunarity, gain, scale)
  119. {
  120.     uniform float amp = 1;
  121.     varying point pp = p;
  122.     varying float sum = 0;
  123.     varying float fw = filtwidth;
  124.     uniform float i;
  125.  
  126.     for (i = 0;  i < octaves;  i += 1) {
  127. #pragma nolint
  128.     sum += amp * filteredVLNoise (pp, fw, scale);
  129.     amp *= gain;  pp *= lacunarity;  fw *= lacunarity;
  130.     }
  131.     return sum;
  132. }
  133.  
  134.  
  135. /* Typical use of vfBm: */
  136. #define VLfBm_default(p)      VLfBm (p, filterwidthp(p), 4, 2, 0.5, 1.0)
  137.  
  138.  
  139.  
  140.  
  141. /* Antialiased turbulence.  Watch out -- the abs() call introduces infinite
  142.  * frequency content, which makes our antialiasing efforts much trickier!
  143.  */
  144. float turbulence (point p; float filtwidth;
  145.                   uniform float octaves, lacunarity, gain)
  146. {
  147.     extern float du, dv;   /* Needed for filterwidth macro */
  148.     uniform float amp = 1;
  149.     varying point pp = p;
  150.     varying float sum = 0, fw = filtwidth;
  151.     uniform float i;
  152.  
  153.     for (i = 0;  i < octaves;  i += 1) {
  154. #pragma nolint
  155.     float n = filteredsnoise (pp, fw);
  156.     sum += amp * filteredabs (n, fw);
  157.     amp *= gain;  pp *= lacunarity;  fw *= lacunarity;
  158.     }
  159.     return sum;
  160. }
  161.  
  162.  
  163. /* Typical use of turbulence: */
  164. #define turbulence_default(p)  turbulence (p, filterwidthp(p), 4, 2, 0.5)
  165.  
  166.  
  167.  
  168.  
  169. /***************************************************************************
  170.  * Voronoi cell noise (a.k.a. Worley noise) functions
  171.  *
  172.  * These functions assume that space is filled with "features" (points
  173.  * of interest).  There are interestingpatterns we can make by
  174.  * figuring out which feature we are closest to, or to what extent
  175.  * we're on the boundary between two features.  Several varieties of
  176.  * these computations are below, categorized by the dimension of their
  177.  * domains, and the number of close features they are interested in.
  178.  *
  179.  * All these functions have similar inputs:
  180.  *   P      - position to test (for 3-D varieties; 2-D varieties use ss,tt)
  181.  *   jitter - how much to jitter the cell center positions (1 is typical,
  182.  *             smaller values make a more regular pattern, larger values
  183.  *             make a more jagged pattern; use jitter >1 at your risk!).
  184.  * And outputs:
  185.  *   f_n    - distance to the nth nearest feature (f1 is closest, f2 is
  186.  *            the distance to the 2nd closest, etc.)
  187.  *   pos_n  - the position of the nth nearest feature.  For 2-D varieties,
  188.  *            these are instead spos_n and tpos_n.
  189.  ***************************************************************************/
  190.  
  191. /* Voronoi cell noise (a.k.a. Worley noise) -- 3-D, 1-feature version. */
  192. void
  193. voronoi_f1_3d (point P;
  194.            float jitter;
  195.            output float f1;
  196.            output point pos1;
  197.     )
  198. {
  199.     point thiscell = point (floor(xcomp(P))+0.5, floor(ycomp(P))+0.5,
  200.                 floor(zcomp(P))+0.5);
  201.     f1 = 1000;
  202.     uniform float i, j, k;
  203.     for (i = -1;  i <= 1;  i += 1) {
  204.         for (j = -1;  j <= 1;  j += 1) {
  205.             for (k = -1;  k <= 1;  k += 1) {
  206.         point testcell = thiscell + vector(i,j,k);
  207.                 point pos = testcell + 
  208.                     jitter * (vector cellnoise (testcell) - 0.5);
  209.         vector offset = pos - P;
  210.                 float dist = offset . offset; /* actually dist^2 */
  211.                 if (dist < f1) {
  212.                     f1 = dist;  pos1 = pos;
  213.                 }
  214.             }
  215.     }
  216.     }
  217.     f1 = sqrt(f1);
  218. }
  219.  
  220.  
  221. /* Voronoi cell noise (a.k.a. Worley noise) -- 3-D, 2-feature version. */
  222. void
  223. voronoi_f1f2_3d (point P;
  224.          float jitter;
  225.          output float f1;  output point pos1;
  226.          output float f2;  output point pos2;
  227.     )
  228. {
  229.     point thiscell = point (floor(xcomp(P))+0.5, floor(ycomp(P))+0.5,
  230.                 floor(zcomp(P))+0.5);
  231.     f1 = f2 = 1000;
  232.     uniform float i, j, k;
  233.     for (i = -1;  i <= 1;  i += 1) {
  234.         for (j = -1;  j <= 1;  j += 1) {
  235.             for (k = -1;  k <= 1;  k += 1) {
  236.         point testcell = thiscell + vector(i,j,k);
  237.                 point pos = testcell + 
  238.                     jitter * (vector cellnoise (testcell) - 0.5);
  239.         vector offset = pos - P;
  240.                 float dist = offset . offset; /* actually dist^2 */
  241.                 if (dist < f1) {
  242.                     f2 = f1;  pos2 = pos1;
  243.                     f1 = dist;  pos1 = pos;
  244.                 } else if (dist < f2) {
  245.                     f2 = dist;  pos2 = pos;
  246.         }
  247.             }
  248.     }
  249.     }
  250.     f1 = sqrt(f1);  f2 = sqrt(f2);
  251. }
  252.  
  253.  
  254. /* Voronoi cell noise (a.k.a. Worley noise) -- 2-D, 1-feature version. */
  255. void
  256. voronoi_f1_2d (float ss, tt;
  257.            float jitter;
  258.            output float f1;
  259.            output float spos1, tpos1;
  260.     )
  261. {
  262.     float sthiscell = floor(ss)+0.5, tthiscell = floor(tt)+0.5;
  263.     f1 = 1000;
  264.     uniform float i, j;
  265.     for (i = -1;  i <= 1;  i += 1) {
  266.     float stestcell = sthiscell + i;
  267.         for (j = -1;  j <= 1;  j += 1) {
  268.         float ttestcell = tthiscell + j;
  269.         float spos = stestcell +
  270.              jitter * (float cellnoise(stestcell, ttestcell) - 0.5);
  271.         float tpos = ttestcell +
  272.          jitter * (float cellnoise(stestcell+23, ttestcell-87) - 0.5);
  273.         float soffset = spos - ss;
  274.         float toffset = tpos - tt;
  275.         float dist = soffset*soffset + toffset*toffset;
  276.         if (dist < f1) {
  277.         f1 = dist;
  278.         spos1 = spos;  tpos1 = tpos;
  279.         }
  280.     }
  281.     }
  282.     f1 = sqrt(f1);
  283. }
  284.  
  285.  
  286. /* Voronoi cell noise (a.k.a. Worley noise) -- 2-D, 2-feature version. */
  287. void
  288. voronoi_f1f2_2d (float ss, tt;
  289.          float jitter;
  290.          output float f1;
  291.          output float spos1, tpos1;
  292.          output float f2;
  293.          output float spos2, tpos2;
  294.     )
  295. {
  296.     float sthiscell = floor(ss)+0.5, tthiscell = floor(tt)+0.5;
  297.     f1 = f2 = 1000;
  298.     uniform float i, j;
  299.     for (i = -1;  i <= 1;  i += 1) {
  300.     float stestcell = sthiscell + i;
  301.         for (j = -1;  j <= 1;  j += 1) {
  302.         float ttestcell = tthiscell + j;
  303.         float spos = stestcell +
  304.            jitter * (cellnoise(stestcell, ttestcell) - 0.5);
  305.         float tpos = ttestcell +
  306.            jitter * (cellnoise(stestcell+23, ttestcell-87) - 0.5);
  307.         float soffset = spos - ss;
  308.         float toffset = tpos - tt;
  309.         float dist = soffset*soffset + toffset*toffset;
  310.         if (dist < f1) {
  311.         f2 = f1;  spos2 = spos1;  tpos2 = tpos1;
  312.         f1 = dist;  spos1 = spos;  tpos1 = tpos;
  313.         } else if (dist < f2) {
  314.         f2 = dist;
  315.         spos2 = spos;  tpos2 = tpos;
  316.         }
  317.     }
  318.     }
  319.     f1 = sqrt(f1);  f2 = sqrt(f2);
  320. }
  321.  
  322.  
  323. #endif /* NOISES_H */
  324.